package am.NotenProgramm.Frame.Panels;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import am.NotenProgramm.Frame.GradePro;
import am.NotenProgramm.objects.Subject;

public class GradePanel extends JPanel implements ActionListener,
		ListSelectionListener, KeyListener {

	// MAIN
	JPanel panelLeft = new JPanel();
	JPanel panelRight = new JPanel();

	// LINKES MAINPANEL
	JPanel panelMainInfo = new JPanel();
	JScrollPane scrollPaneSubjects;

	// SCROLL PANNEL
	JPanel panelScroll = new JPanel();
	public JList listSubjects;
	private boolean lastWasCreateNew = false;

	// INFOPANEL
	double compPoints = 0.0;
	double avGrade = 0.0;
	double minPoints = 0.0;
	double plusPoints = 0.0;
	JLabel labelCompensationInfo = new JLabel(" "
			+ GradePro.rb.getString("labelCompensationInfo") + " " + compPoints);
	JLabel labelAverageGrade = new JLabel(" "
			+ GradePro.rb.getString("labelAverageGrade") + " " + avGrade);
	JLabel labelPlusPoints = new JLabel(" "
			+ GradePro.rb.getString("labelPlusPoints") + " " + plusPoints);
	JLabel labelMinusPoints = new JLabel(" "
			+ GradePro.rb.getString("labelMinusPoints") + " " + minPoints);

	// RECHTES MAINPANEL
	JPanel[] panelGradeSettings;
	GradeMainPanel[] panelGrades;

	public GradePanel(Dimension size) {

		setSize(size);
		// setBackground(Color.BLACK);
		setLayout(null);

		// LINKES HAUPTPANEL
		panelLeft.setBorder(BorderFactory
				.createBevelBorder(BevelBorder.LOWERED));
		panelLeft.setLocation(0, 0);
		panelLeft
				.setSize((int) (this.getWidth() * (1.0 / 3)), this.getHeight());
		// panelLeft.setBackground(Color.GRAY);
		initPanelLeft();
		add(panelLeft);
		//panelGradeSettings = new GradeSettingsPanel(-1);
		// RECHTES HAUPTPANEL
		panelRight.setBorder(BorderFactory
				.createBevelBorder(BevelBorder.LOWERED));
		panelRight.setLocation(panelLeft.getWidth(), 0);
		panelRight.setSize(this.getWidth() - panelLeft.getWidth(),
				this.getHeight());
		// panelRight.setBackground(Color.RED);
		initPanelRight();
		add(panelRight);
	}

	private void initPanelLeft() {
		panelLeft.setLayout(null);

		// LIST
		// Load topics from Main
		String subjectStrings[] = new String[GradePro.myProfile.getSubjects().length + 1];
		for (int i = 0; i < subjectStrings.length - 1; i++) {
			subjectStrings[i] = GradePro.myProfile.getSubjects()[i].getName();
		}
		subjectStrings[subjectStrings.length - 1] = GradePro.rb
				.getString("newSubject");
		listSubjects = new JList(subjectStrings);
		listSubjects.setFont(new Font(Font.DIALOG, Font.BOLD, 24));
		listSubjects.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		listSubjects.addListSelectionListener(this);
		listSubjects.addKeyListener(this);

		scrollPaneSubjects = new JScrollPane(listSubjects,
				ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
				ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		scrollPaneSubjects.setLocation(0, 0);
		scrollPaneSubjects.setSize(panelLeft.getWidth(),
				(int) (panelLeft.getHeight() * 0.7));
		// scrollPaneGrades.addKeyListener(this);

		panelLeft.add(scrollPaneSubjects);

		// HAUPTINFO PANEL
		panelMainInfo.setBorder(BorderFactory
				.createBevelBorder(BevelBorder.LOWERED));
		panelMainInfo.setLocation(0, (int) (panelLeft.getHeight() * 0.7));
		panelMainInfo.setSize(panelLeft.getWidth(),
				(int) (panelLeft.getHeight() * 0.27));
		// panelMainInfo.setBackground(Color.YELLOW);
		panelMainInfo.setLayout(new GridLayout(4, 1));

		panelMainInfo.add(labelAverageGrade);
		panelMainInfo.add(labelCompensationInfo);
		panelMainInfo.add(labelPlusPoints);
		panelMainInfo.add(labelMinusPoints);
		panelLeft.add(panelMainInfo);

		refreshInfoBox();


	}

	private void initPanelRight() { // RECHTS
		panelRight.setLayout(null);

		// NOTENEINSTELLUNGEN
		/*panelGradeSettings.setBorder(BorderFactory
				.createBevelBorder(BevelBorder.LOWERED));
		panelGradeSettings.setLocation(0, (int) (panelRight.getHeight() * 0.7));
		panelGradeSettings.setSize(panelRight.getWidth(),
				(int) (panelRight.getHeight() * 0.3));*/
		// panelGradeSettings.setBackground(Color.GREEN);
		

		// Fächer-Panel-Setup
		
		panelGradeSettings = new GradeSettingsPanel[GradePro.myProfile.getSubjects().length];
		for(int i = 0; i < panelGradeSettings.length; i++){
			panelGradeSettings[i] = new GradeSettingsPanel(i);
			panelGradeSettings[i].setBorder(BorderFactory
					.createBevelBorder(BevelBorder.LOWERED));
			panelGradeSettings[i].setLocation(0, (int) (panelRight.getHeight() * 0.7));
			panelGradeSettings[i].setSize(panelRight.getWidth(),
					(int) (panelRight.getHeight() * 0.3));
			panelRight.add(panelGradeSettings[i]);
			panelGradeSettings[i].setVisible(false);
		}
		panelGrades = new GradeMainPanel[GradePro.myProfile.getSubjects().length];
		for (int i = 0; i < panelGrades.length; i++) {
			panelGrades[i] = new GradeMainPanel(
					GradePro.myProfile.getSubjects()[i], new Dimension(
							panelRight.getWidth(), panelRight.getHeight()
									- panelGradeSettings[0].getHeight()));
			panelGrades[i].setBorder(BorderFactory
					.createBevelBorder(BevelBorder.LOWERED));
			panelRight.add(panelGrades[i]);
			panelGrades[i].setVisible(false);
		}
	}

	public void refreshPanels() {
		this.setVisible(false);
		remove(panelLeft);
		panelLeft = new JPanel();
		panelLeft.setBorder(BorderFactory
				.createBevelBorder(BevelBorder.LOWERED));
		panelLeft.setLocation(0, 0);
		panelLeft
				.setSize((int) (this.getWidth() * (1.0 / 3)), this.getHeight());
		// panelLeft.setBackground(Color.GRAY);
		initPanelLeft();
		add(panelLeft);
		panelLeft.setVisible(true);
		remove(panelRight);
		panelRight = new JPanel();
		panelRight.setBorder(BorderFactory
				.createBevelBorder(BevelBorder.LOWERED));
		panelRight.setLocation(panelLeft.getWidth(), 0);
		panelRight.setSize(this.getWidth() - panelLeft.getWidth(),
				this.getHeight());
		// panelRight.setBackground(Color.RED);
		initPanelRight();
		add(panelRight);
		panelRight.setVisible(true);
		this.repaint();
		this.setVisible(true);
	}

	public void refreshInfoBox() {
		// Calculate Averages and Compensation Points
		double tmpAverage = 0.0;
		minPoints = 0.0;
		plusPoints = 0.0;
		int tmpDivisor = 0;
		for (int i = 0; i < GradePro.myProfile.getSubjects().length; i++) {
			if(GradePro.myProfile.getSubjects()[i].getAverage() != 0.0){	
				tmpDivisor += GradePro.myProfile.getSubjects()[i].getSubjectWeight();
				tmpAverage += GradePro.myProfile.getSubjects()[i].getAverage()*GradePro.myProfile.getSubjects()[i].getSubjectWeight();
				if (0 <= GradePro.myProfile.getSubjects()[i].getAverage() - 4) {
					plusPoints += GradePro.myProfile.getSubjects()[i].getSubjectWeight()*(Math.round(2 * (GradePro.myProfile.getSubjects()[i]
							.getAverage() - 4)) / 2.0);
				} else {
					minPoints += GradePro.myProfile.getSubjects()[i].getSubjectWeight()*(Math.abs(Math.round(2 * (GradePro.myProfile
							.getSubjects()[i].getAverage() - 4))));
				}
			}
		}
		compPoints = plusPoints - minPoints;
		minPoints = minPoints / 2;
		avGrade = Math.round(1000 * tmpAverage
				/ tmpDivisor) / 1000.0;
		// Display the calculated Values
		labelCompensationInfo
				.setText(" " + GradePro.rb.getString("labelCompensationInfo") + " "
						+ compPoints);
		labelAverageGrade.setText(" " + GradePro.rb.getString("labelAverageGrade")
				+ " " + avGrade);
		labelPlusPoints.setText(" " + GradePro.rb.getString("labelPlusPoints")
				+ " " + plusPoints);
		labelMinusPoints.setText(" " + GradePro.rb.getString("labelMinusPoints")
				+ " " + minPoints + " (x2)");
		panelMainInfo.repaint();
		panelMainInfo.setVisible(true);
	}

	public void createNewSubject() {
		String inputStr = null;
		inputStr = JOptionPane.showInputDialog(new JFrame(), GradePro.rb.getString("setName"),
				GradePro.rb.getString("newSubject"), JOptionPane.OK_OPTION);
		if (inputStr != null && !inputStr.equals("")) {
			boolean isAlreadyHere = false;
			for (int i = 0; i < GradePro.myProfile.getSubjects().length; i++) {
				if (inputStr.toLowerCase()
						.equals(GradePro.myProfile.getSubjects()[i].getName()
								.toLowerCase())) {
					isAlreadyHere = true;
				}
			}
			if (!isAlreadyHere) {
				GradePro.myProfile.addSubject(new Subject(inputStr));
				GradePro.myStream.saveProfile(GradePro.myProfile);
				System.out.println(GradePro.rb.getString("newSubject") + inputStr);
				// Recreate the panel
				refreshPanels();
				GradePro.mainFrame.panelStatistics.refresh();
			} else {
				System.out.println(inputStr
						+ GradePro.rb.getString("alreadyExists"));
				JOptionPane.showMessageDialog(null,
						inputStr + " " + GradePro.rb.getString("alreadyExists"));
			}
		}

	}

	public void deleteSubject() {
		if (!listSubjects.getSelectedValue().toString()
				.equals(GradePro.rb.getString("newSubject"))) {
			// Check which Subject to delete
			for (int i = 0; i < GradePro.myProfile.getSubjects().length; i++) {
				if (listSubjects.getSelectedValue().toString()
						.equals(GradePro.myProfile.getSubjects()[i].getName())) {
					// Create a Comfirmation Dialog
					if (JOptionPane
							.showConfirmDialog(
									new JFrame(),
									GradePro.rb.getString("reallyDelete")
											+ GradePro.myProfile.getSubjects()[i]
													.getName() + "?",
									"Warning", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
						GradePro.myProfile.removeSubjects(i);
						refreshPanels();
						GradePro.mainFrame.panelStatistics.refresh();
					}
				}
			}
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub

	}

	// GET SELECTION AND SHOW THE RIGHT PANEL
	@Override
	public void valueChanged(ListSelectionEvent e) {
		// TODO Auto-generated method stub
		
		// Save Changes of the current Subject
		for (int i = 0; i < panelGrades.length; i++) {
			if (listSubjects.getSelectedIndex() != -1) {
				if (panelGrades[i].getSubject().getName().equals(listSubjects.getSelectedValue().toString())) {
					panelGrades[i].saveGrades();
				}
			}
		}
		
		// Check create new Subject
		if (listSubjects.getSelectedIndices().length > 0) {
			if (listSubjects.getSelectedValue().toString()
					.equals(GradePro.rb.getString("newSubject"))) {
				for (int j = 0; j < panelGrades.length; j++) {
					panelGrades[j].setVisible(false);
					panelGradeSettings[j].setVisible(false);
				}
				listSubjects.clearSelection();
				if (!lastWasCreateNew) {
					lastWasCreateNew = true;
					createNewSubject();
					lastWasCreateNew = false;
				}
			} else {
				// Check which Subject to show
				lastWasCreateNew = false;
				for (int i = 0; i < GradePro.myProfile.getSubjects().length; i++) {
					if (listSubjects.getSelectedValue().toString()
							.equals(GradePro.myProfile.getSubjects()[i].getName())) {
						for (int j = 0; j < panelGrades.length; j++) {
							if (panelGrades[j]
									.getSubject()
									.getName()
									.equals(listSubjects.getSelectedValue()
											.toString())) {
								panelGrades[j].setVisible(true);
								panelGradeSettings[j].setVisible(true);
								
							} else {
								panelGrades[j].setVisible(false);
								panelGradeSettings[j].setVisible(false);
							}
						}
					}
				}
			}
		}
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyPressed(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
			if (!listSubjects.getSelectedValue().toString().equals("")) {
				deleteSubject();
			}
		}
	}

}
